/*
 * CVoc_Process.cpp
 *
 *  Created on: 2012-4-12
 *      Author: li.zhaoping
 */

#include "CVoc_Process.h"

#include <string.h>
#include<stdlib.h>

#include "../CDownLoadTask.h"
#include "../utility/pcre_wrapper.h"
#include "easyLog.h"

#define RULER_VOC_ROOT 	"ruler_voc_0"
#define RULER_VOC_1 			"ruler_voc_1"
#define RULER_VOC_2 			"ruler_voc_2"

CVoc_Process::CVoc_Process() :
	pcreRoot_(0), pcreRoot_1_(0), pcreRoot_2_(0), pcreNode1_(0),
			pcreNode1_1_(0), pcreNode1_2_(0), pcreNode2_(0) {
}

CVoc_Process::~CVoc_Process() {
}

bool CVoc_Process::Init(CTaskCallback *cb) {
	bool ret = false;
	cb_ = cb;

	INFO_("CVoc_Process::Init\n");
	pcreRoot_
			= pcre_new_express("<td class=\"tbfltd2\" align=\"left\".*?</td>");
	pcreRoot_1_ = pcre_new_express("<a.*?</a>");
	pcreRoot_2_ = pcre_new_express("href=\".*?\"");

	pcreNode1_ = pcre_new_express("<div id=\"message.*?</div>");
	pcreNode1_1_ = pcre_new_express("<img.*?/>");
	pcreNode1_2_ = pcre_new_express("src=\".*?jpg\"");

	pcreNode2_ = pcre_new_express("vod2");

	ret = pcreRoot_ && pcreRoot_1_ && pcreRoot_2_ && pcreNode1_ && pcreNode1_1_
			&& pcreNode1_2_ && pcreNode2_;
	if (!ret) {//err
		if (pcreRoot_ != 0) pcre_free_express(pcreRoot_);
		if (pcreRoot_1_ != 0) pcre_free_express(pcreRoot_1_);
		if (pcreRoot_2_ != 0) pcre_free_express(pcreRoot_2_);
		if (pcreNode1_ != 0) pcre_free_express(pcreNode1_);
		if (pcreNode1_1_ != 0) pcre_free_express(pcreNode1_1_);
		if (pcreNode1_2_ != 0) pcre_free_express(pcreNode1_2_);
		if (pcreNode2_ != 0) pcre_free_express(pcreNode2_);
	}

	return ret;
}

bool CVoc_Process::UnInit() {
	if (pcreRoot_ != 0) pcre_free_express(pcreRoot_);
	if (pcreRoot_1_ != 0) pcre_free_express(pcreRoot_1_);
	if (pcreRoot_2_ != 0) pcre_free_express(pcreRoot_2_);
	if (pcreNode1_ != 0) pcre_free_express(pcreNode1_);
	if (pcreNode1_1_ != 0) pcre_free_express(pcreNode1_1_);
	if (pcreNode1_2_ != 0) pcre_free_express(pcreNode1_2_);
	if (pcreNode2_ != 0) pcre_free_express(pcreNode2_);

}

process_type_t CVoc_Process::GetProcessType(const char* strUrl,
		const char* strRuler) {
	if (strstr(strRuler, RULER_VOC_2) != 0) {
		return PROCESS_FILE;
	}
	return PROCESS_BUF;
}

const char *CVoc_Process::GetRootRulerName() {
	return RULER_VOC_ROOT;
}

bool CVoc_Process::ProcessBuffer(const char *buf, long bufsize, const char *strUrl,
		const char *strRuler) {

	//	DEBUG_("CVoc_Process::ProcessBuffer [\033[1;31m%s\033[0m][%s][%s]\n", buf, strUrl,strRuler);
	bool ret = true;
	char *data = strdup(buf);
	int i = 0;
	while (data[i] != 0) {
		if (data[i] == '\n') {
			data[i] = ' ';//space
		}
		i++;
	}

	if (strstr(strRuler, RULER_VOC_ROOT) != 0) {
		parserRoot(data, strUrl, strRuler);
	}
	else if (strstr(strRuler, RULER_VOC_1) != 0) {
		parserNode1(data, strUrl, strRuler);
	}
	else if (strstr(strRuler, RULER_VOC_2) != 0) {
		std::string downFileName = "";
		std::string url = strUrl;
		if (url.find(".jpg") != -1) {
			int p = url.rfind("/");
			downFileName = url.substr(p + 1);
		}
		if (downFileName != ""){
			FILE * fnew = fopen(downFileName.c_str(), "wb+");
			if (fnew != NULL) {
				fwrite(buf, bufsize, 1, fnew);
				fclose(fnew);
				DEBUG_("writeFile[%s] success\n",downFileName.c_str());
			}
		}

	}
	else {
		ret = false;
		ERR_("Unknow ruler!\n");
	}
	return ret;
}

bool CVoc_Process::ProcessFile(const char *sFile, const char *strUrl,
		const char *strRuler) {

	return false;
}

bool CVoc_Process::parserNode1(char *data, const char *strUrl,
		const char *strRuler) {

	int dataSize = (int) strlen(data);
	int ovector[3];
	memset(ovector, -1, sizeof(ovector));
	int offset = 0, retStart = 0, retLen = 0;
	int imatch = 0;
	for (;;) {
		int rt = pcre_exc_express(pcreNode1_, data, dataSize, offset,
				&retStart, &retLen);
		if (rt == -1) {
			//			ERR_("CVoc_Process::ProcessBuffer -1 \n");
			break;
		}
		else {
			offset = retStart + retLen;
			char *substring_start = data + retStart;
			//				printf("[%3d]Match==>\033[1;31m%.*s\033[0m\n", imatch, retLen,
			//						substring_start);
			imatch++;

			//do parser <a
			{
				int offset1 = 0, retStart1 = 0, retLen1 = retLen;
				int rt1 = pcre_exc_express(pcreNode1_1_, substring_start,
						retLen1, 0, &retStart1, &retLen1);
				if (rt1 == -1) {
					//					DEBUG_("CVoc_Process::ProcessBuffer -2 \n");
				}
				else {
					char *substring_start1 = substring_start + retStart1;
					//printf("url==>[%.*s]\n", retLen1, substring_start1);
					//do parser <href
					{
						int offset2 = 0, retStart2 = 0, retLen2 = retLen1;
						int rt2 = pcre_exc_express(pcreNode1_2_,
								substring_start1, retLen2, 0, &retStart2,
								&retLen2);
						if (rt2 == -1) {

						}
						else {
							char *substring_start2 = substring_start1
									+ retStart2 + 5;
							char* str_url = (char*) malloc(retLen2 - 6 + 1);
							memset(str_url, 0, sizeof(str_url));
							sprintf(str_url, "%.*s", retLen2 - 6,
									substring_start2);
							//							printf("[%3d]Match==>url[\033[1;31m%s\033[0m]\n",
							//									imatch, str_url);
							TaskData_t *tData = new TaskData_t;
							//							tData->strUrl += "http://bbs.voc.com.cn/";
							tData->strUrl = str_url;
							tData->strRule = RULER_VOC_2;
							tData->strUrlParam = "";
							tData->bDone = false;
							//							INFO_("------[ %s ]\n",tData->strUrl.c_str());
							if (cb_ != NULL) cb_->Invoke(2, (void*) tData);
						}
					}
				}

			}
		}
	}

	return true;
}

bool CVoc_Process::parserRoot(char *data, const char *strUrl,
		const char *strRuler) {
	int dataSize = (int) strlen(data);
	int ovector[3];
	memset(ovector, -1, sizeof(ovector));
	int offset = 0, retStart = 0, retLen = 0;
	int imatch = 0;
	for (;;) {
		int rt = pcre_exc_express(pcreRoot_, data, dataSize, offset, &retStart,
				&retLen);
		if (rt == -1) {
			//			ERR_("CVoc_Process::ProcessBuffer -1 \n");
			break;
		}
		else {
			offset = retStart + retLen;
			char *substring_start = data + retStart;
			//				printf("[%3d]Match==>\033[1;31m%.*s\033[0m\n", imatch, retLen,
			//						substring_start);
			imatch++;

			//do parser <a
			{
				int offset1 = 0, retStart1 = 0, retLen1 = retLen;
				int rt1 = pcre_exc_express(pcreRoot_1_, substring_start,
						retLen1, 0, &retStart1, &retLen1);
				if (rt1 == -1) {
					//					DEBUG_("CVoc_Process::ProcessBuffer -2 \n");
				}
				else {
					char *substring_start1 = substring_start + retStart1;
					//printf("url==>[%.*s]\n", retLen1, substring_start1);
					//do parser <href
					{
						int offset2 = 0, retStart2 = 0, retLen2 = retLen1;
						int rt2 = pcre_exc_express(pcreRoot_2_,
								substring_start1, retLen2, 0, &retStart2,
								&retLen2);
						if (rt2 == -1) {

						}
						else {
							char *substring_start2 = substring_start1
									+ retStart2 + 6;
							char* str_url = (char*) malloc(retLen2 - 7 + 1);
							memset(str_url, 0, sizeof(str_url));
							sprintf(str_url, "%.*s", retLen2 - 7,
									substring_start2);
							//							printf("[%3d]Match==>url[\033[1;31m%s\033[0m]\n",
							//									imatch, str_url);
							TaskData_t *tData = new TaskData_t;
							tData->strUrl += "http://bbs.voc.com.cn/";
							tData->strUrl += str_url;
							tData->strRule = RULER_VOC_1;
							tData->strUrlParam = "";
							tData->bDone = false;
							//							INFO_("------[ %s ]\n",tData->strUrl.c_str());
							if (cb_ != NULL) cb_->Invoke(2, (void*) tData);
						}
					}
				}

			}
//						if (imatch > 5)
//							break;
		}
	}

	return true;
}

